home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / emacs.lha / emacs-19.16 / src / crt0.c < prev    next >
C/C++ Source or Header  |  1993-06-16  |  15KB  |  586 lines

  1. /* C code startup routine.
  2.    Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU Emacs.
  5.  
  6. GNU Emacs is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GNU Emacs is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Emacs; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. /* The standard Vax 4.2 Unix crt0.c cannot be used for Emacs
  22.    because it makes `envron' an initialized variable.
  23.    It is easiest to have a special crt0.c on all machines
  24.    though I don't know whether other machines actually need it.  */
  25.  
  26. /* On the vax and 68000, in BSD4.2 and USG5.2,
  27.    this is the data format on startup:
  28.   (vax) ap and fp are unpredictable as far as I know; don't use them.
  29.   sp ->  word containing argc
  30.          word pointing to first arg string
  31.      [word pointing to next arg string]... 0 or more times
  32.      0
  33. Optionally:
  34.      [word pointing to environment variable]... 1 or more times
  35.      ...
  36.      0
  37. And always:
  38.      first arg string
  39.      [next arg string]... 0 or more times
  40. */
  41.  
  42. /* On the 16000, at least in the one 4.2 system I know about,
  43.   the initial data format is
  44.   sp ->  word containing argc
  45.          word containing argp
  46.          word pointing to first arg string, and so on as above
  47. */
  48.  
  49. #ifdef emacs
  50. #include "config.h"
  51. #endif
  52.  
  53. /*        ********  WARNING ********
  54.     Do not insert any data definitions before data_start!
  55.     Since this is the first file linked, the address of the following
  56.     variable should correspond to the start of initialized data space.
  57.     On some systems this is a constant that is independent of the text
  58.     size for shared executables.  On others, it is a function of the
  59.     text size. In short, this seems to be the most portable way to
  60.     discover the start of initialized data space dynamically at runtime,
  61.     for either shared or unshared executables, on either swapping or
  62.     virtual systems.  It only requires that the linker allocate objects
  63.     in the order encountered, a reasonable model for most Unix systems.
  64.     Similarly, note that the address of _start() should be the start
  65.     of text space.   Fred Fish, UniSoft Systems Inc.  */
  66.  
  67. int data_start = 0;
  68.  
  69. #ifdef NEED_ERRNO
  70. int errno;
  71. #endif
  72.  
  73. #ifndef DONT_NEED_ENVIRON
  74. char **environ;
  75. #endif
  76.  
  77. #ifndef static
  78. /* On systems where the static storage class is usable, this function
  79.    should be declared as static.  Otherwise, the static keyword has
  80.    been defined to be something else, and code for those systems must
  81.    take care of this declaration appropriately.  */
  82. static start1 ();
  83. #endif
  84.  
  85. #if defined(orion) || defined(pyramid) || defined(celerity) || defined(ALLIANT) || defined(clipper) || defined(sps7)
  86.  
  87. #if defined(sps7) && defined(V3x)
  88.         asm("    section    10");
  89.         asm("    ds.b    0xb0");
  90. #endif
  91.  
  92. #ifdef ALLIANT
  93. /* _start must initialize _curbrk and _minbrk on the first startup;
  94.    when starting up after dumping, it must initialize them to what they were
  95.    before the dumping, since they are in the shared library and
  96.    are not dumped.  See ADJUST_EXEC_HEADER in m-alliant.h.  */
  97. extern unsigned char *_curbrk, *_minbrk;
  98. extern unsigned char end;
  99. unsigned char *_setbrk = &end;
  100. #ifdef ALLIANT_2800
  101. unsigned char *_end = &end;
  102. #endif
  103. #endif
  104.  
  105. #ifndef DUMMIES
  106. #define DUMMIES
  107. #endif
  108.  
  109. _start (DUMMIES argc, argv, envp)
  110.      int argc;
  111.      char **argv, **envp;
  112. {
  113. #ifdef ALLIANT
  114. #ifdef ALLIANT_2800
  115.   _curbrk = _end;
  116.   _minbrk = _end;
  117. #else
  118.   _curbrk = _setbrk;
  119.   _minbrk = _setbrk;
  120. #endif
  121. #endif
  122.  
  123.   environ = envp;
  124.  
  125.   exit (main (argc, argv, envp));
  126. }
  127.  
  128. #endif /* orion or pyramid or celerity or alliant or clipper */
  129.  
  130. #if defined (ns16000) && !defined (sequent) && !defined (UMAX) && !defined (CRT0_DUMMIES)
  131.  
  132. _start ()
  133. {
  134. /* On 16000, _start pushes fp onto stack */
  135.   start1 ();
  136. }
  137.  
  138. /* ignore takes care of skipping the fp value pushed in start.  */
  139. static
  140. start1 (ignore, argc, argv)
  141.      int ignore;
  142.      int argc;
  143.      register char **argv;
  144. {
  145.   environ = argv + argc + 1;
  146.  
  147.   if (environ == *argv)
  148.     environ--;
  149.   exit (main (argc, argv, environ));
  150. }
  151. #endif /* ns16000, not sequent and not UMAX, and not the CRT0_DUMMIES method */
  152.  
  153. #ifdef UMAX
  154. _start()
  155. {
  156.     asm("    exit []            # undo enter");
  157.     asm("    .set    exitsc,1");
  158.     asm("    .set    sigcatchall,0x400");
  159.  
  160.     asm("    .globl    _exit");
  161.     asm("    .globl    start");
  162.     asm("    .globl    __start");
  163.     asm("    .globl    _main");
  164.     asm("    .globl    _environ");
  165.     asm("    .globl    _sigvec");
  166.     asm("    .globl    sigentry");
  167.  
  168.     asm("start:");
  169.     asm("    br    .xstart");
  170.     asm("    .org    0x20");
  171.     asm("    .double    p_glbl,0,0xf00000,0");
  172.     asm("    .org    0x30");
  173.     asm(".xstart:");
  174.     asm("    adjspb    $8");
  175.     asm("    movd    8(sp),0(sp)    # argc");
  176.     asm("    addr    12(sp),r0");
  177.     asm("    movd    r0,4(sp)    # argv");
  178.     asm("L1:");
  179.     asm("    movd    r0,r1");
  180.     asm("    addqd    $4,r0");
  181.     asm("    cmpqd    $0,0(r1)    # null args term ?");
  182.     asm("    bne    L1");
  183.     asm("    cmpd    r0,0(4(sp))    # end of 'env' or 'argv' ?");
  184.     asm("    blt    L2");
  185.     asm("    addqd    $-4,r0        # envp's are in list");
  186.     asm("L2:");
  187.     asm("    movd    r0,8(sp)    # env");
  188.     asm("    movd    r0,@_environ    # indir is 0 if no env ; not 0 if env");
  189.     asm("    movqd    $0,tos        # setup intermediate signal handler");
  190.     asm("    addr    @sv,tos");
  191.     asm("    movzwd    $sigcatchall,tos");
  192.     asm("    jsr    @_sigvec");
  193.     asm("    adjspb    $-12");
  194.     asm("    jsr    @_main");
  195.     asm("    adjspb    $-12");
  196.     asm("    movd    r0,tos");
  197.     asm("    jsr    @_exit");
  198.     asm("    adjspb    $-4");
  199.     asm("    addr    @exitsc,r0");
  200.     asm("    svc");
  201.     asm("    .align    4        # sigvec arg");
  202.     asm("sv:");
  203.     asm("    .double    sigentry");
  204.     asm("    .double    0");
  205.     asm("    .double    0");
  206.  
  207.     asm("    .comm    p_glbl,1");
  208. }
  209. #endif /* UMAX */
  210.  
  211. #ifdef CRT0_DUMMIES
  212.  
  213. /* Define symbol "start": here; some systems want that symbol.  */
  214. #ifdef DOT_GLOBAL_START
  215. asm("    .text        ");
  216. asm("    .globl start    ");
  217. asm("    start:        ");
  218. #endif /* DOT_GLOBAL_START */
  219.  
  220. #ifdef NODOT_GLOBAL_START
  221. asm("    text        ");
  222. asm("    global start    ");
  223. asm("    start:        ");
  224. #endif /* NODOT_GLOBAL_START */
  225.  
  226. #ifdef m68000
  227.  
  228. /* GCC 2.1, when optimization is turned off, seems to want to push a
  229.    word of garbage on the stack, which screws up the CRT0_DUMMIES
  230.    hack.  So we hand-code _start in assembly language.  */
  231. asm(".text            ");
  232. asm("    .even            ");
  233. asm(".globl __start        ");
  234. asm("__start:            ");
  235. asm("    link a6,#0        ");
  236. asm("    jbsr _start1        ");
  237. asm("    unlk a6            ");
  238. asm("    rts            ");
  239.  
  240. #else /* not m68000 */
  241.  
  242. _start ()
  243. {
  244. /* On vax, nothing is pushed here  */
  245. /* On sequent, bogus fp is pushed here  */
  246.   start1 ();
  247. }
  248.  
  249. #endif /* possibly m68000 */
  250.  
  251. static
  252. start1 (CRT0_DUMMIES argc, xargv)
  253.      int argc;
  254.      char *xargv;
  255. {
  256.   register char **argv = &xargv;
  257.   environ = argv + argc + 1;
  258.  
  259.   if ((char *)environ == xargv)
  260.     environ--;
  261.   exit (main (argc, argv, environ));
  262. }
  263. #else /* not CRT0_DUMMIES */
  264.  
  265. /* "m68k" and "m68000" both stand for m68000 processors,
  266.    but with different program-entry conventions.
  267.    This is a kludge.  Now that the CRT0_DUMMIES mechanism above exists,
  268.    most of these machines could use the vax code above
  269.    with some suitable definition of CRT0_DUMMIES.
  270.    Then the symbol m68k could be flushed.
  271.    But I don't want to risk breaking these machines
  272.    in a version 17 patch release, so that change is being put off.  */
  273.  
  274. #ifdef m68k            /* Can't do it all from C */
  275.     asm ("    global    _start");
  276.     asm ("    text");
  277.     asm ("_start:");
  278. #ifndef NU
  279. #ifdef STRIDE
  280.     asm ("    comm    havefpu%,2");
  281. #else /* m68k, not STRIDE */
  282.     asm ("  comm    splimit%,4");
  283. #endif /* STRIDE */
  284.     asm ("    global    exit");
  285.     asm ("    text");
  286. #ifdef STRIDE
  287.     asm ("    trap    &3");
  288.     asm ("    mov.w    %d0,havefpu%");
  289. #else /* m68k, not STRIDE */
  290.       asm ("    mov.l    %d0,splimit%");
  291. #endif /* STRIDE */
  292. #endif /* not NU */
  293.     asm ("    jsr    start1");
  294.     asm ("    mov.l    %d0,(%sp)");
  295.     asm ("    jsr    exit");
  296.     asm ("    mov.l    &1,%d0");    /* d0 = 1 => exit */
  297.     asm ("    trap    &0");
  298. #else /* m68000, not m68k */
  299.  
  300. #ifdef m68000
  301.  
  302. #ifdef ISI68K
  303. /* Added by ESM Sun May 24 12:44:02 1987 to get new ISI library to work */
  304. /* Edited by Ray Mon May 15 15:59:56 EST 1989 so we can compile with gcc */
  305. #if defined(BSD4_3) && !defined(__GNUC__)
  306. static foo () {
  307. #endif
  308.     asm ("    .globl  is68020");
  309.     asm ("is68020:");
  310. #ifndef BSD4_3
  311.     asm ("    .long   0x00000000");
  312.     asm ("    .long   0xffffffff");
  313. /* End of stuff added by ESM */
  314. #endif
  315.     asm ("    .text");
  316.     asm ("    .globl    __start");
  317.     asm ("__start:");
  318.     asm ("    .word 0");
  319.     asm ("    link    a6,#0");
  320.     asm ("    jbsr    _start1");
  321.     asm ("    unlk    a6");
  322.     asm ("    rts");
  323. #if defined(BSD4_3) && !defined(__GNUC__)
  324.       }
  325. #endif
  326. #else /* not ISI68K */
  327.  
  328. _start ()
  329. {
  330. #ifdef sun
  331. #ifdef LISP_FLOAT_TYPE
  332.   finitfp_();
  333. #endif
  334. #endif     
  335. /* On 68000, _start pushes a6 onto stack  */
  336.   start1 ();
  337. }
  338. #endif /* not ISI68k */
  339. #endif /* m68000 */
  340. #endif /* m68k */
  341.  
  342. #if defined(m68k) || defined(m68000)
  343. /* ignore takes care of skipping the a6 value pushed in start.  */
  344. static
  345. #if defined(m68k)
  346. start1 (argc, xargv)
  347. #else
  348. start1 (ignore, argc, xargv)
  349. #endif
  350.      int argc;
  351.      char *xargv;
  352. {
  353.   register char **argv = &xargv;
  354.   environ = argv + argc + 1;
  355.  
  356.   if ((char *)environ == xargv)
  357.     environ--;
  358. #ifdef sun_68881
  359.   asm("    jsr     f68881_used");
  360. #endif
  361. #ifdef sun_fpa
  362.   asm("    jsr     ffpa_used");
  363. #endif
  364. #ifdef sun_soft
  365.   asm("    jsr     start_float");
  366. #endif
  367.   exit (main (argc, argv, environ));
  368. }
  369.  
  370. #endif /* m68k or m68000 */
  371.  
  372. #endif /* not CRT0_DUMMIES */
  373.  
  374. #ifdef hp9000s300
  375. int argc_value;
  376. char **argv_value;
  377. #ifdef OLD_HP_ASSEMBLER
  378.     asm("   text");
  379.     asm("    globl __start");
  380.     asm("    globl _exit");
  381.     asm("    globl _main");
  382.     asm("__start");
  383.     asm("    dc.l    0");
  384.     asm("    subq.w    #0x1,d0");
  385.     asm("    move.w    d0,float_soft");
  386.     asm("    move.l    0x4(a7),d0");
  387.     asm("    beq.s    skip_1");
  388.     asm("    move.l    d0,a0");
  389.     asm("    clr.l    -0x4(a0)");
  390.     asm("skip_1");
  391.     asm("    move.l    a7,a0");
  392.     asm("    subq.l    #0x8,a7");
  393.     asm("    move.l    (a0),(a7)");
  394.     asm("    move.l    (a0),_argc_value");
  395.     asm("    addq.l    #0x4,a0");
  396.     asm("    move.l    a0,0x4(a7)");
  397.     asm("    move.l    a0,_argv_value");
  398.     asm("incr_loop");
  399.     asm("    tst.l    (a0)+");
  400.     asm("    bne.s    incr_loop");
  401.     asm("    move.l    0x4(a7),a1");
  402.     asm("    cmp.l    (a1),a0");
  403.     asm("    blt.s    skip_2");
  404.     asm("    subq.l    #0x4,a0");
  405.     asm("skip_2");
  406.     asm("    move.l    a0,0x8(a7)");
  407.     asm("    move.l    a0,_environ");
  408.     asm("    jsr    _main");
  409.     asm("    addq.l    #0x8,a7");
  410.     asm("    move.l    d0,-(a7)");
  411.     asm("    jsr    _exit");
  412.     asm("    move.w    #0x1,d0");
  413.     asm("    trap    #0x0");
  414.     asm("    comm    float_soft,4");
  415. /* float_soft is allocated in this way because C would
  416.    put an underscore character in its name otherwise. */
  417.  
  418. #else /* new hp assembler */
  419.  
  420.     asm("    text");
  421.         asm("   global  float_loc");
  422.         asm("   set     float_loc,0xFFFFB000");
  423.      asm("    global    fpa_loc");
  424.     asm("    set    fpa_loc,0xfff08000");
  425.     asm("    global    __start");
  426.     asm("    global    _exit");
  427.     asm("    global    _main");
  428.     asm("__start:");
  429.     asm("    byte    0,0,0,0");
  430.     asm("    subq.w    &1,%d0");
  431.     asm("    mov.w    %d0,float_soft");
  432.     asm("    mov.w    %d1,flag_68881");
  433. #ifndef HPUX_68010
  434.     asm("    beq.b    skip_float");
  435.     asm("    fmov.l    &0x7400,%fpcr");
  436. /*    asm("    fmov.l    &0x7480,%fpcr"); */
  437. #endif /* HPUX_68010 */
  438.     asm("skip_float:");
  439.     asm("    mov.l    %a0,%d0");
  440.     asm("    add.l    %d0,%d0");
  441.     asm("    subx.w    %d1,%d1");
  442.     asm("    mov.w    %d1,flag_68010");
  443.     asm("    add.l    %d0,%d0");
  444.     asm("    subx.w    %d1,%d1");
  445.     asm("    mov.w    %d1,flag_fpa");
  446.     asm("    tst.l    %d2");
  447.     asm("    ble.b    skip_3");
  448.     asm("    lsl    flag_68881");
  449.     asm("    lsl    flag_fpa");
  450.     asm("skip_3:");
  451.     asm("    mov.l    4(%a7),%d0");
  452.     asm("    beq.b    skip_1");
  453.     asm("    mov.l    %d0,%a0");
  454.     asm("    clr.l    -4(%a0)");
  455.     asm("skip_1:");
  456.     asm("    mov.l    %a7,%a0");
  457.     asm("    subq.l    &8,%a7");
  458.     asm("    mov.l    (%a0),(%a7)");
  459.     asm("    mov.l    (%a0),_argc_value");
  460.     asm("    addq.l    &4,%a0");
  461.     asm("    mov.l    %a0,4(%a7)");
  462.     asm("    mov.l    %a0,_argv_value");
  463.     asm("incr_loop:");
  464.     asm("    tst.l    (%a0)+");
  465.     asm("    bne.b    incr_loop");
  466.     asm("    mov.l    4(%a7),%a1");
  467.     asm("    cmp.l    %a0,(%a1)");
  468.     asm("    blt.b    skip_2");
  469.     asm("    subq.l    &4,%a0");
  470.     asm("skip_2:");
  471.     asm("    mov.l    %a0,8(%a7)");
  472.     asm("    mov.l    %a0,_environ");
  473.     asm("    jsr    _main");
  474.     asm("    addq.l    &8,%a7");
  475.     asm("    mov.l    %d0,-(%a7)");
  476.     asm("    jsr    _exit");
  477.     asm("    mov.w    &1,%d0");
  478.     asm("    trap    &0");
  479.     asm("    comm    float_soft, 4");
  480.     asm("    comm    flag_68881, 4");
  481.     asm("    comm    flag_68010, 4");
  482.     asm("    comm    flag_68040, 4");
  483.     asm("    comm    flag_fpa, 4");
  484.  
  485. #endif /* new hp assembler */
  486. #endif /* hp9000s300 */
  487.  
  488. #ifdef GOULD
  489.  
  490. /* startup code has to be in near text rather
  491.    than fartext as allocated by the C compiler. */
  492.     asm("    .text");
  493.     asm("    .align    2");
  494.     asm("    .globl    __start");
  495.     asm("    .text");
  496.     asm("__start:");
  497. /* setup base register b1 (function base). */
  498.     asm("    .using    b1,.");
  499.     asm("    tpcbr    b1");
  500. /* setup base registers b3 through b7 (data references). */
  501.     asm("    file    basevals,b3");
  502. /* setup base register b2 (stack pointer); it should be
  503.    aligned on a 8-word boundary; but because it is pointing
  504.    to argc, its value should be remembered (in r5). */
  505.     asm("    movw    b2,r4");
  506.     asm("    movw    b2,r5");
  507.     asm("    andw    #~0x1f,r4");
  508.     asm("    movw    r4,b2");
  509. /* allocate stack frame to do some work. */
  510.     asm("    subea    16w,b2");
  511. /* initialize signal catching for UTX/32 1.2; this is
  512.    necessary to make restart from saved image work. */
  513.     asm("    movea    sigcatch,r1");
  514.     asm("    movw    r1,8w[b2]");
  515.     asm("    svc    #1,#150");
  516. /* setup address of argc for start1. */
  517.     asm("    movw    r5,8w[b2]");
  518.     asm("   func    #1,_start1");
  519.     asm("    halt");
  520. /* space for ld to store base register initial values. */
  521.     asm("    .align    5");
  522.     asm("basevals:");
  523.     asm("    .word    __base3,__base4,__base5,__base6,__base7");
  524.  
  525. static
  526. start1 (xargc)
  527.      int *xargc;
  528. {
  529.   register int    argc;
  530.   register char **argv;
  531.  
  532.   argc = *xargc;
  533.   argv = (char **)(xargc) + 1;
  534.   environ = argv + argc + 1;
  535.  
  536.   if (environ == argv)
  537.     environ--;
  538.   exit (main (argc, argv, environ));
  539.  
  540. }
  541.  
  542. #endif /* GOULD */
  543.  
  544. #ifdef elxsi
  545. #include <elxsi/argvcache.h>
  546.  
  547. extern char **environ;
  548. extern int    errno;
  549. extern void    _init_doscan(), _init_iob();
  550. extern char    end[];
  551. char        *_init_brk = end;
  552.  
  553. _start()
  554. {
  555.   environ = exec_cache.ac_envp;
  556.   brk (_init_brk);
  557.   errno = 0;
  558.   _init_doscan ();
  559.   _init_iob ();
  560.   _exit (exit (main (exec_cache.ac_argc,
  561.              exec_cache.ac_argv,
  562.              exec_cache.ac_envp)));
  563. }
  564. #endif /* elxsi */
  565.  
  566.  
  567. #ifdef sparc
  568. asm (".global __start");
  569. asm (".text");
  570. asm ("__start:");
  571. asm ("    mov    0, %fp");
  572. asm ("    ld    [%sp + 64], %o0");
  573. asm ("    add    %sp, 68, %o1");
  574. asm ("    sll    %o0, 2,    %o2");
  575. asm ("    add    %o2, 4,    %o2");
  576. asm ("    add    %o1, %o2, %o2");
  577. asm ("    sethi    %hi(_environ), %o3");
  578. asm ("    st    %o2, [%o3+%lo(_environ)]");
  579. asm ("    andn    %sp, 7,    %sp");
  580. asm ("    call    _main");
  581. asm ("    sub    %sp, 24, %sp");
  582. asm ("    call    __exit");
  583. asm ("    nop");
  584.  
  585. #endif /* sparc */
  586.